// Setup basic express server
const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');
const socketIo = require('socket.io');
const path = require('path');
const selfsigned = require('selfsigned');
const AdmZip = require('adm-zip');
// const namespace = require('socket.io/lib/namespace');

const app = express();
// sever version 4.8.1 == client version 3.1.0(socketio and socketio_tls )
console.log('server version: 4.8.1');
console.log('http client version: socketio 3.1.0');
console.log('https client version: socketio_tls 3.1.0');
const httpPort = 3100; //socketio
const httpsPort = 3101; // socketio_tls

// 定义证书和密钥的路径
const certDir = path.join(__dirname, 'certs');
const zipFilePath = path.join(__dirname, 'certs.zip');
const keyPath = path.join(certDir, 'key.pem');
const certPath = path.join(certDir, 'cert.pem');

// 检查证书文件是否存在，如果不存在则生成新的
let httpsOptions;
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
  httpsOptions = {
    key: fs.readFileSync(keyPath),
    cert: fs.readFileSync(certPath)
  };
} else {
  // 生成自签名证书
  const attrs = [{ name: 'commonName', value: 'localhost' }];
  const pems = selfsigned.generate(attrs, { days: 365 });
  
  // 确保证书目录存在
  if (!fs.existsSync(certDir)) {
    fs.mkdirSync(certDir);
  }
  
  // 将密钥和证书保存到文件
  fs.writeFileSync(keyPath, pems.private);
  fs.writeFileSync(certPath, pems.cert);
  
  httpsOptions = {
    key: pems.private,
    cert: pems.cert
  };
}
// 压缩 certs 目录为 certs.zip
if (fs.existsSync(certDir)) {
  try {
    const zip = new AdmZip();
    zip.addLocalFolder(certDir);
    zip.writeZip(zipFilePath);
    console.log(`✅ 证书目录已压缩为: ${zipFilePath}`);
  } catch (err) {
    console.error(`❌ 压缩证书目录失败:`, err);
  }
} else {
  console.warn(`⚠️ 证书目录不存在，跳过压缩: ${certDir}`);
}

// 创建 HTTP 服务器
const httpServer = http.createServer(app);

// 创建 HTTPS 服务器
const httpsServer = https.createServer(httpsOptions, app);

// 创建 Socket.IO 实例，绑定到 HTTP 和 HTTPS 服务器
const io = socketIo();
io.attach(httpServer);
io.attach(httpsServer);


// Routing
app.use(express.static(path.join(__dirname, 'public')));



// 启动 HTTP 服务器
httpServer.listen(httpPort, () => {
  console.log(`HTTP server listening on port ${httpPort}`);
});

// 启动 HTTPS 服务器
httpsServer.listen(httpsPort, () => {
  console.log(`HTTPS server listening on port ${httpsPort}`);
});


// Chatroom

let numUsers = 0;
let sentMessageCount = 0; // 全局计数器
io.on('connection', (socket) => {
  console.log('a user connected:', socket.id, socket.handshake.url);
  numUsers++;
  console.log('用户连接，当前用户数:', numUsers);

  let addedUser = false;
  socket.emit('login', {"numUsers": numUsers});

  // when the client emits 'new message', this listens and executes
  socket.on('new message', (data) => { 
    console.log(data)
    socket.emit('new message', { // broadcast是广播，除了自己以外的所有人
      username: socket.username,
      message: data
    });
    // we tell the client to execute 'new message'
    // socket.broadcast.emit('new message', { // broadcast是广播，除了自己以外的所有人
    //   username: socket.username,
    //   message: data
    // });
  
  });

  // setTimeout(() => {
  //   socket.disconnect(true); // 断开连接
  // }, 5000); 
  
  
  // setInterval(() => {
  //   socket.emit('response', JSON.stringify({ message: 'default namespace 定时服务器响应' }));
  // }, 10000); // 每10秒发送一次
  // // when the client emits 'add user', this listens and executes
  
  
  socket.on('add user', (username) => {
      console.log(username)
    if (addedUser) return;

    // we store the username in the socket session for this client
    socket.username = username;
    ++numUsers;
    addedUser = true;

    const messages1 = [
      {"message": {"username": "robot", "message": "Welcome to the chat room!"}},
    ]

  //   // 计数发送消息
  //   function sendMessages() {
  //     messages1.forEach(function(msg) {
  //       sentMessageCount++; // 递增计数器

  //       // 深拷贝消息对象，避免修改原始数据
  //       const messageWithCount = JSON.parse(JSON.stringify(msg.message));

  //       // 在消息对象中添加计数属性
  //       messageWithCount.count = sentMessageCount;

  //       // 发送包含计数值的消息
  //       socket.emit("login", messageWithCount);

  //       // // 记录日志
  //       // console.log(`已发送消息数量: ${sentMessageCount}`, messageWithCount);

  //       // 动态输出
  //       process.stdout.write(`已发送消息数量: ${sentMessageCount}\r`);

  //    });
  //  }
  //    setInterval(sendMessages, 100);

 

    // echo globally (all clients) that a person has connected
    
    socket.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', () => {
    socket.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', () => {
    socket.emit('stop typing', {
      username: socket.username
    });
  });


  // when the user disconnects.. perform this
  socket.on('disconnect', () => {
    console.log('user disconnected:', socket.id);
    if (addedUser) {
      --numUsers;
      console.log('用户断开，当前用户数:', numUsers);
      // echo globally that this client has left
      socket.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});

// 定义命名空间 'nsp_test'
const nspTest = io.of('/nsp_test');

nspTest.on('connection', (socket) => {
  console.log('a user connected to nsp_test namespace:', socket.id);

  // 示例事件处理
  socket.on('message', (data) => {
    console.log('Received message in nsp_test namespace:', data);
  });
  
  // // 定时发送 'response' 事件
  // setInterval(() => {
  //   socket.emit('response', JSON.stringify({ message: 'nsp_test namespace 定时服务器响应' }));
  // }, 10000); // 每10秒发送一次

  socket.on('disconnect', () => {
    console.log('user disconnected from nsp_test namespace:', socket.id);
  });
});
